package com.eric.utils.json;

import com.alibaba.fastjson.*;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.util.Collections;
import java.util.List;
import java.util.Map;


/**
 * @author lk
 * @version 创建时间：2018/10/18 11:21
 */
public class FastJsonUtil {

    /**
     *  1、字段为 boolean 类型的时候，如果反序列化的时候，这个字段没有，默认是 false
     *  2、字段为 int 类型的时候，则会为0
     *  就是 基本数据类型，会直接是默认值
     *
     *
     *  它的优势：快，比Jackson快20%左右，Google的Gson是最慢的
     *  它的bug：
     *      1、处理时间的时候，格式会有问题
     *      2、复杂字符串，它识别不了
     */



    private FastJsonUtil(){}

    /**
     * Object -> Map
     */
    public static Map<Object, Object> beanToMap(Object bean) {
        return bean == null ? null : JSON.parseObject(JSON.toJSONString(bean), new TypeReference<>() {});
    }


    /**
     * list -> JSONArray
     */
    public static JSONArray listToListJson(List<Object> list){
        return JSONObject.parseArray(JSON.toJSONString(list));
    }



    public static JSONObject toJsonObject(Object object) {
        return JSON.parseObject(JSON.toJSONString(object));
    }


    /**
     * 将对象转成 JSON 数组字符串
     */
    public static String toArrayString(Object object) {
        return toJsonString(Collections.singletonList(object));
    }


    /**
     * 将对象转成 JSON 字符串（去掉循环引用标记）
     */
    public static String toJsonString(Object object) {
        return JSONObject.toJSONString(object, filter, SerializerFeature.DisableCircularReferenceDetect);

    }

    /**
     * 将对象转成 JSON 字符串（去掉循环引用标记，map 中含有 null 的依然保留）
     */
    public static String toJsonStringWithNull(Object object) {
        return JSONObject.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
    }


    /**
     * 为 null、字符串为空、list 空 list 都不会被转成 JSONString
     */
    static PropertyFilter filter = (source, key, value) -> {
        if (value == null) {
            return false;
        }
        if (value instanceof String && ((String) value).isEmpty()) {
            return false;
        }
        return !(value instanceof List) || ((List<?>) value).size() != 0;
    };

}
